package com.yonyou.pmclouds.projectpart.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.projectpart.entity.ProjectPartRefVO;
import com.yonyou.pmclouds.projectpart.entity.ProjectPartVO;
import com.yonyou.pmclouds.projectpart.service.IProjectpartQryService;
import com.yonyou.pmclouds.projectpart.service.IProjectpartService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RequestMapping("/mobile/projectpart")
@RestController
@Slf4j
public class ProjectpartMobileController {

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private IProjectpartService projectpartService;

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private IProjectpartQryService projectpartQryService;
    /**
     * 获取项目下能被参照的工程部位
     *
     * @param pkProject
     * @return
     * @throws BusinessException
     */
    @GetMapping("/ref")
    public ProjectPartRefVO[] queryRefVOs(@RequestParam("pkProject") String pkProject) throws BusinessException {
        List<ProjectPartRefVO> projectPartVOs = projectpartQryService.queryRefVOs(pkProject);
        return buildTree(projectPartVOs);
    }

    @PostMapping("/insert")
    public ProjectPartRefVO[] insertForMobile(@RequestBody @Validated({ProjectPartVO.QueryValid.class}) ProjectPartVO para,BindingResult errors) throws BusinessException {
        String errorMsg = getErrorMsg(errors);
        if(errorMsg.length() > 0){
            throw  new BusinessException(errorMsg);
        }
        if(StringUtils.isEmpty(para.getPkTenant())){
            String tenantid = RuntimeEnvironment.getTenantId();
            log.info("移动端新增的租户ID（从上下文获取）：" + tenantid);
            if(StringUtils.isEmpty(tenantid)){
                throw new BusinessException("获取不到租户信息");
            }
            para.setPkTenant(tenantid);
        }
        para.setCreator(RuntimeEnvironment.getLoginUserId());
        ProjectPartVO addData = projectpartService.insertForMobile(para);
        ProjectPartRefVO[] result = buildTree(projectpartQryService.queryRefVOs(para.getPkProject()));
        if(ArrayUtils.isNotEmpty(result)){
            result[0].setOperatePK(addData.getPkProjectpart());
        }
        return result;
    }

    /**
     * 将所有工程部位构造树
     *
     * @param projectPartVOs
     * @return
     */
    private ProjectPartRefVO[] buildTree(List<ProjectPartRefVO> projectPartVOs) {
        List<ProjectPartRefVO> result = new ArrayList<ProjectPartRefVO>();
        if (projectPartVOs.isEmpty())
            return new ProjectPartRefVO[]{};

        // 节点和所有子节点映射
        Map<String, List<ProjectPartRefVO>> selfToChildrenMap = new HashMap<>();
        projectPartVOs.forEach(partVO -> {
            if (selfToChildrenMap.get(partVO.getPkParent()) == null) {
                selfToChildrenMap.put(partVO.getPkParent(), new ArrayList<>());
            }
            selfToChildrenMap.get(partVO.getPkParent()).add(partVO);
        });

        // 给childProjectpart赋值（根据scode排序）
        projectPartVOs.forEach(partVO -> {
            List<ProjectPartRefVO> children = selfToChildrenMap.get(partVO.getPkProjectpart());
            if (children != null) {
                children.sort(Comparator.comparing(ProjectPartRefVO::getScode));
                partVO.setChildProjectpart(children.toArray(new ProjectPartRefVO[0]));
            }
        });

        // 根节点排序
        List<ProjectPartRefVO> rootVOs = selfToChildrenMap.get("");
        if(rootVOs == null){
            rootVOs = selfToChildrenMap.get(null) == null ? selfToChildrenMap.get("~") : selfToChildrenMap.get(null);
        }
        if (rootVOs != null)
            rootVOs.sort(Comparator.comparing(ProjectPartRefVO::getScode));
        return rootVOs.toArray(new ProjectPartRefVO[]{});
    }

    private String getErrorMsg(BindingResult errors){
        String errorMsg = "";
        if(errors.hasErrors()){
            List<ObjectError> errorList = errors.getAllErrors();
            for(int i = 0; i< errorList.size(); i++){
                ObjectError error  =  errorList.get(i);
                if(!StringUtils.isEmpty(error.getDefaultMessage())){
                    if(i != errorList.size()-1){
                        errorMsg += error.getDefaultMessage()+",";
                    }else{
                        errorMsg += error.getDefaultMessage();
                    }
                }
            }
        }
        return errorMsg;
    }
}
